/*
 * DeltaHandler.cpp
 *
 * */

#include "DeltaHandler.h"
#include "SepararString.h"

DeltaHandler::~DeltaHandler() {}

std::string mensajeAEnviar(std::string fileFullPath,std::string modo,
		std::string diferencialesSerializados = "NO", std::string fecha = "NO"){
	std::string msj(modo);
	msj += " ";
	std::vector<std::string> vec;
	separarString(fileFullPath, '/', vec);
	msj += vec[vec.size()-1];
	if(fecha != "NO"){
		msj += " ";
		msj += fecha;
	}
	if(diferencialesSerializados != "NO"){
		msj += " ";
		msj += diferencialesSerializados;
	}

	return msj;
}

void DeltaHandler::manejarDelta(const std::string& comando,
		const std::string& fileFullPath, bool soloSincronizo) {
	std::string tipoDelta;
	std::string fecha;
	if (soloSincronizo) {
		tipoDelta = comando;
	} else {
		// Parsea el comando.
		std::vector<string> vec;
		separarString(comando, ' ', vec);
		tipoDelta = vec[0];
		fecha = vec[1];;
	}

	std::string mensajeRecibido;
	if (tipoDelta.compare(EMISORDELTA) == 0) {
		// El cliente es emisor del delta
		emisor = true;
		EmisorDelta emisor;
		emisor.Iniciar(fileFullPath.c_str());

		// Emisor calcular los rolling checksum del file en comun
		emisor.CalcularHashesVarios();
		// Recibo paquetes de hashes (MD5 y ADLER32 de bloques no solapados)

		std::string msj(mensajeAEnviar(fileFullPath, UPDATERECEPTOR));
		this->comunicador.enviarMensaje(msj);
		this->comunicador.recibirMensaje(mensajeRecibido);

		// Serializamos datos transmitidos
		DatosTrasmitidos<PaqueteHashReceptor> hashesReceptor(mensajeRecibido);
		// Lista de los cambios diferenciales en los archivos
		DatosTrasmitidos<Diferencial> datosTransmitidos =
				emisor.compararConHashesDelReceptor(hashesReceptor);

		// Serializo todos los diferenciales
		std::string diferencialesSerializados = datosTransmitidos.Serializar();

		std::string msjDif(mensajeAEnviar(fileFullPath, UPDATERECEPTOR2,
				diferencialesSerializados, fecha));
		this->comunicador.enviarMensaje(msjDif);

	} else {
		// El cliente es receptor del delta
		ReceptorDelta receptor;

		receptor.Iniciar(fileFullPath.c_str());

		receptor.CalcularHashesVarios();

		std::string serializacion = receptor.Serializar();

		std::string msj(mensajeAEnviar(fileFullPath, UPDATEEMISOR, serializacion));
		this->comunicador.enviarMensaje(msj);
		this->comunicador.recibirMensaje(mensajeRecibido);

		DatosTrasmitidos<Diferencial> datosTransmitidos(mensajeRecibido);
		receptor.UpdatearArchivoRespectoAemisor(mensajeRecibido);
	}

	if (soloSincronizo) return;
	std::string msjOK = mensajeAEnviar(fileFullPath, UPDATEOK);
	this->comunicador.enviarMensaje(msjOK);
	this->comunicador.recibirMensaje(msjOK);
}
